﻿using System;
using System.Linq;
using System.Web;
using Amba.KeyValueStorage.Models;
using Orchard;
using Orchard.Data;

namespace Amba.KeyValueStorage.Services
{
    public interface IKeyValueStorageService : IDependency
    {
        string Get(string key);
        void Set(string key, string value);
        string GenerateKey();
    }

    public class KeyValueStorageService : IKeyValueStorageService
    {
        private readonly IRepository<KeyValueRecord> _keyValueRepo;

        public KeyValueStorageService(IRepository<KeyValueRecord> keyValueRepo)
        {
            _keyValueRepo = keyValueRepo;
        }

        private void SaveId(string key, long id)
        {
            if (HttpContext.Current == null)
                return;
            HttpContext.Current.Items["amba.kv_" + key] = id;
        }

        private long GetId(string key)
        {
            if (HttpContext.Current == null)
                return -1;
            if (HttpContext.Current.Items.Contains("amba.kv_" + key))
                return (long)HttpContext.Current.Items["amba.kv_" + key];
            return -1;
        }

        private KeyValueRecord FindKeyValuePair(string key)
        {
            var id = GetId(key);
            KeyValueRecord keyValuePair = null;
            if (id > 0)
                keyValuePair = _keyValueRepo.Table.FirstOrDefault(x => x.Id == id);
            if (keyValuePair == null)
                keyValuePair = _keyValueRepo.Table.FirstOrDefault(x => x.DataKey == key);
            return keyValuePair;
        }
        
        public string Get(string key)
        {
            var keyValuePair = FindKeyValuePair(key);
            if (keyValuePair == null)
                return string.Empty;
            return keyValuePair.Value;
        }

        public void Set(string key, string value)
        {
            var keyValuePair = FindKeyValuePair(key);
            if (keyValuePair == null)
            {
                keyValuePair = new KeyValueRecord();
                keyValuePair.DataKey = key;
                keyValuePair.Value = value;
                keyValuePair.LastUpdate = DateTime.UtcNow;
                _keyValueRepo.Create(keyValuePair);
            }
            else
            {
                keyValuePair.LastUpdate = DateTime.UtcNow;
                keyValuePair.Value = value;
                _keyValueRepo.Update(keyValuePair);
            }
            SaveId(key, keyValuePair.Id);
        }

        private const string symbols = "01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ_-";
        public string GenerateKey()
        {
            var rnd = new Random();
            for (int j = 4; j < 10; j++)
            {
                var result = "";
                for (int i = 0; i < j; i++)
                {
                    result += symbols[rnd.Next(symbols.Length - 1)];
                }
                if (!_keyValueRepo.Table.Any(x => x.DataKey == result))
                {
                    return result;
                }
            }
            return Guid.NewGuid().ToString();
        }
    }
}